import { _decorator, Button, CCInteger, Component, EventMouse, Input, instantiate, Label, Node, Slider, tween, Tween, TweenEasing, UITransform, Vec2, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('EasingSample')
export class EasingSample extends Component {
    private eases: TweenEasing[] = [
        "linear",
        "smooth",
        "fade",
        "constant",
        "quadIn",
        "quadOut",
        "quadInOut",
        "quadOutIn",
        "cubicIn",
        "cubicOut",
        "cubicInOut",
        "cubicOutIn",
        "quartIn",
        "quartOut",
        "quartInOut",
        "quartOutIn",
        "quintIn",
        "quintOut",
        "quintInOut",
        "quintOutIn",
        "sineIn",
        "sineOut",
        "sineInOut",
        "sineOutIn",
        "expoIn",
        "expoOut",
        "expoInOut",
        "expoOutIn",
        "circIn",
        "circOut",
        "circInOut",
        "circOutIn",
        "elasticIn",
        "elasticOut",
        "elasticInOut",
        "elasticOutIn",
        "backIn",
        "backOut",
        "backInOut",
        "backOutIn",
        "bounceIn",
        "bounceOut",
        "bounceInOut",
        "bounceOutIn"
    ];

    private curEasing: TweenEasing = "linear";

    @property(Slider)
    private durationSlider: Slider;
    @property(CCInteger)
    public duration: number = 1;
    @property(Label)
    private durationLabel: Label;
    private MAX_DURATION: number = 10;

    private canvas: UITransform;

    @property(Node)
    private panel: Node;

    @property(Node)
    private character: Node;

    @property(Node)
    private easingSelect: Node;

    @property(Label)
    private easingValue: Label;

    @property(Node)
    private optionsNode: Node;

    @property(Node)
    private optionContent: Node;

    @property(Node)
    private optionItem: Node;

    start() {
        this.canvas = this.getComponent(UITransform);
        this.durationSlider.node.on("slide", this.setDuration, this);
        this.setDuration();

        this.panel.on(Input.EventType.MOUSE_DOWN, (event: EventMouse) => {
            Tween.stopAllByTarget(this.character);
            this.optionsNode.active = false;

            let position: Vec2 = event.getUILocation();
            let targetPosition: Vec3 = new Vec3(position.x - (this.canvas.contentSize.x / 2), position.y - (this.canvas.contentSize.y / 2), 0)
            tween(this.character).to(this.duration, {
                position: targetPosition
            }, {
                easing: this.curEasing
            }).start();
        });

        this.initOptions();

        this.setEase(this.curEasing);
    }

    setDuration() {
        this.duration = this.durationSlider.progress * this.MAX_DURATION;
        this.durationLabel.string = this.duration.toFixed(2) + 's';
    }

    initOptions() {
        for (let i = 0; i < this.eases.length; i++) {
            const ease = this.eases[i];
            let optionNode = instantiate(this.optionItem);
            optionNode.name = ease;
            optionNode.getComponent(Label).string = ease;
            optionNode.setParent(this.optionContent);
            optionNode.on(Node.EventType.MOUSE_DOWN, (event: EventMouse) => {
                this.setEase(optionNode.name as TweenEasing);
                // 这里竟然要阻止冒泡，否则会触发select的事件！！
                event.propagationStopped = true;
            }, this);
        }

        this.easingSelect.on(Input.EventType.MOUSE_DOWN, (event: EventMouse) => {
            this.optionsNode.active = true;
        }, this);
    }

    setEase(ease: TweenEasing) {
        this.curEasing = ease;
        this.easingValue.string = this.curEasing;
        this.optionsNode.active = false;
    }
}